package com.capinfo.commons.project.service.security.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;

import com.capinfo.commons.project.model.security.SystemRole;
import com.capinfo.commons.project.model.security.SystemViewStamp;
import com.capinfo.commons.project.parameter.security.SystemRoleParameter;
import com.capinfo.commons.project.parameter.security.SystemViewStampParameter;
import com.capinfo.commons.project.service.security.SystemViewStampService;
import com.capinfo.framework.dao.SearchCriteria.OrderRow;
import com.capinfo.framework.dao.SearchCriteriaBuilder;
import com.capinfo.framework.dao.impl.restriction.RestrictionExpression;
import com.capinfo.framework.service.impl.CommonsDataOperationServiceImpl;

public class SystemViewStampServiceImpl extends CommonsDataOperationServiceImpl<SystemViewStamp, SystemViewStampParameter> implements SystemViewStampService {
	
	private static final Log logger = LogFactory.getLog(SystemViewStampService.class);
	
	public SearchCriteriaBuilder<SystemViewStamp> getSearchCriteriaBuilder(SystemViewStampParameter parameter) {
		
		SearchCriteriaBuilder<SystemViewStamp> searchCriteriaBuilder = super.getSearchCriteriaBuilder(parameter);

		searchCriteriaBuilder.addQueryCondition("name", RestrictionExpression.LIKE_OP, parameter.getEntity().getName());
		searchCriteriaBuilder.addOrderCondition("id", OrderRow.ORDER_DESC);

		return searchCriteriaBuilder;
	}

	@Override
	public SystemViewStamp saveOrUpdate(SystemViewStampParameter parameter) {

		return getCacheParameter(parameter).getNewEntity();
	}
	
	protected CacheParameter getCacheParameter(SystemViewStampParameter parameter) {

		CacheParameter cacheParameter = new CacheParameter();
		SystemViewStamp newEntity = null;
		if( parameter.getEntity().getId() == null ){
			
			newEntity = parameter.getEntity();
		} else {
			
			newEntity = this.getObjectById(parameter);
			
			getGeneralService().fetchLazyProperty(newEntity, "roles", false);
			cacheParameter.setOriginalRoles(newEntity.getRoles());
			cacheParameter.setOriginalName(newEntity.getName());
			
			BeanUtils.copyProperties(parameter.getEntity(), newEntity, new String[]{"enabled","resources","roles"});
		}
		if( null != newEntity ) {

			newEntity.setRoles(arrayToRoles(parameter.getRoleIds()));
			
			getGeneralService().saveOrUpdate(newEntity);
			
			cacheParameter.setNewEntity(newEntity);
		}
		
		return cacheParameter;
	}
	
	@Override
	public List<SystemViewStamp> getAllViewStamps() {
		SearchCriteriaBuilder<SystemViewStamp> searchCriteriaBuilder = new SearchCriteriaBuilder<SystemViewStamp>(SystemViewStamp.class);
		return getGeneralService().getObjects(searchCriteriaBuilder.build());
	}

	protected class CacheParameter {
		
		private SystemViewStamp newEntity;
		private Set<SystemRole> originalRoles;
		private String originalName;
		
		public CacheParameter() {}

		public SystemViewStamp getNewEntity() {
			return newEntity;
		}

		public void setNewEntity(SystemViewStamp newEntity) {
			this.newEntity = newEntity;
		}

		public Set<SystemRole> getOriginalRoles() {
			return originalRoles;
		}

		public void setOriginalRoles(Set<SystemRole> originalRoles) {
			this.originalRoles = originalRoles;
		}

		public String getOriginalName() {
			return originalName;
		}

		public void setOriginalName(String originalName) {
			this.originalName = originalName;
		}

	}

	private Set<SystemRole> arrayToRoles(Long[] ids){

		Set<SystemRole> roles = new HashSet<SystemRole>();
		String idStr = "";
		for(Long id: ids){
			idStr += id + ",";
		}
		if(org.apache.commons.lang.StringUtils.isNotBlank(idStr) ) {

			if(idStr.indexOf(",") == 0) {
				idStr = idStr.substring(1,idStr.length());
			}
			if(idStr.lastIndexOf(",")== idStr.length()-1) {
				idStr = idStr.substring(0,idStr.length()-1);
			}

			List<SystemRole> roleList = new ArrayList<SystemRole>();
			if(idStr.length()!= 0){
				SearchCriteriaBuilder<SystemRole> searchCriteriaBuilder = new SearchCriteriaBuilder<SystemRole>(SystemRole.class);
				searchCriteriaBuilder.addAdditionalRestrictionSql("ID in(" + idStr + ")");
				roleList = this.getGeneralService().getObjects(searchCriteriaBuilder.build());
			}
			roles = new HashSet<SystemRole>(roleList);
		}
		
		return roles;
	}
	
	public boolean validatorNameExists(SystemViewStampParameter parameter) {
		SystemViewStamp systemRole = parameter.getEntity();
		SearchCriteriaBuilder<SystemViewStamp> searchCriteriaBuilder = new SearchCriteriaBuilder<SystemViewStamp>(SystemViewStamp.class);
		
		searchCriteriaBuilder.addQueryCondition("name", RestrictionExpression.EQUALS_OP, systemRole.getName());
		searchCriteriaBuilder.addQueryCondition("enabled", RestrictionExpression.EQUALS_OP, Boolean.TRUE);
		if (systemRole.getId() != null) {
			searchCriteriaBuilder.addQueryCondition("id", RestrictionExpression.NOT_EQUALS_OP, systemRole.getId());
		}
		return getGeneralService().getCount(searchCriteriaBuilder.build()) > 0 ? Boolean.TRUE : Boolean.FALSE;
	}
}
